<?php

namespace app\common\library\xmwechat\offiaccount;

use app\common\library\xmwechat\SingletonTrait;
use app\common\library\xmwechat\WechatService;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\OfficialAccount\Application;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use think\exception\HttpResponseException;
use think\Response;

/**
 * 公众号服务
 */
class OaService extends WechatService
{
    protected ?Application $app;
    protected string $accessToken;

    use SingletonTrait;

    /**
     * @throws InvalidArgumentException
     */
    public function __construct()
    {
        parent::__construct();
        if (empty($this->offiAccountConfig['app_id']) || empty($this->offiAccountConfig['secret'])) {
            $this->result('请配置公众号appid或secret');
        }
        $this->app         = new Application([
            'app_id' => $this->offiAccountConfig['app_id'],
            'secret' => $this->offiAccountConfig['secret'],
        ]);
        $accessToken       = $this->app->getAccessToken();
        $this->accessToken = $accessToken->getToken();
    }

    /**
     * 公众号网页授权 发起授权
     * https://easywechat.com/6.x/oauth.html
     * @throws \Exception
     * @author jsjxsz <QQ:1365962177>
     */
    public function getRedirectUrl(): string
    {
        try {
            $redirectUrl = $this->offiAccountConfig['redirect_url'];
            return $this->app->getOAuth()
                ->scopes(['snsapi_userinfo'])
                ->redirect($redirectUrl);
        } catch (InvalidArgumentException $e) {
            $this->result($e->getMessage());
        }
    }

    /**
     * 公众号网页授权 处理授权回调
     * https://easywechat.com/6.x/oauth.html
     * @param string $code
     * @throws \Exception
     * @author jsjxsz <QQ:1365962177>
     */
    public function oauthCallback(string $code): array
    {
        try {
            return $this->app->getOAuth()
                ->scopes(['snsapi_userinfo'])
                ->userFromCode($code)
                ->getRaw();
        } catch (InvalidArgumentException $e) {
            $this->result($e->getMessage());
        }
    }

    /**
     * 公众号发送模板消息
     * @param string $openid 接收者openid
     * @param string $template_id 模板ID
     * @param string $url 模板跳转链接（海外账号没有跳转能力）不跳转可不填写
     * @param array $miniprogram 跳小程序所需数据，不需跳小程序可不用传该数据(appid、pagepath)，小程序appid必须已绑定关联当前公众号
     * @param array $data 模板数据
     * @return bool
     * @throws ClientExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ServerExceptionInterface
     * @throws TransportExceptionInterface
     * @throws \Exception
     * @author jsjxsz <QQ:1365962177>
     */
    public function sendTemplateMessage(string $openid, string $template_id, array $data, string $url = '', array $miniprogram = []): bool
    {
        try {
            $response = $this->app->getClient()->postJson('cgi-bin/message/template/send?access_token=' . $this->accessToken, [
                'touser'      => $openid,
                'template_id' => $template_id,
                'url'         => $url,
                'miniprogram' => $miniprogram,
                'data'        => $data
            ]);
            if ($response->isFailed()) {
                // 出错了，处理异常
                $this->result($response->getContent());
            }
            $result = json_decode($response->getContent(), true);
            if ($result['errcode'] == 0) {
                return true;
            }
        } catch (\Exception $e) {
            $this->result($e->getMessage());
        }
        return false;
    }

}